'use strict';

const { Controller } = require('egg');
const sendToWormhole = require('stream-wormhole');
const rule = {
    BucketName: [
        { required: true, message: '桶名不能为空' },
        {
            validator(rule, value, callback, source, options) {
                const pattern = /^image|video$/;
                if (pattern.test(value)) {
                    return callback();
                }
                callback({ message: `桶名只能为: ${pattern}` });
            }
        }
    ]
};

class UtilsFile extends Controller {
    /**
  * @api {get} /UtilsFile 获取列表
  * @apiGroup UtilsFile
  */
    async index() {
        const { ctx, app, config } = this;
        const {
            pageNow = 0,
            pageSize = 10,
            type = ''
        } = ctx.query;

        const result = await app.mysql.select(config.baseTable.files, {
            limit: parseInt(pageSize),
            offset: parseInt(pageNow),
            orders: [['id', 'desc']],
            where: {
                type
            }
        });
        const sql_total = `SELECT count(id) FROM ${config.baseTable.files} WHERE type = '${type}' `;
        const [{ 'count(id)': totalUserNum }] = await app.mysql.query(sql_total);
        ctx.returnBody(200, `${type}文件列表获取成功`, {
            list: result,
            totalUserNum
        });
    }

    /**
  * @api {get} /UtilsFile/:id 获取详情
  * @apiGroup UtilsFile
  */
    async show() {
        const { ctx } = this;

        ctx.returnBody(200, '进入了获取详情接口');
    }

    /**
  * @api {post} /UtilsFile 创建数据
  * @apiGroup UtilsFile
  */
    async create() {
        const { ctx, service, app, config } = this;
        const stream = await ctx.getFileStream();
        const {
            'bucket-name': BucketName,
            used
        } = ctx.headers;

        const userRule = {
            used: [
                {
                    validator(rule, value, callback) {
                        const pattern = /^\w*_{1}\d*$/;
                        if (pattern.test(value)) {
                            return callback();
                        }
                        callback({ message: `使用者格式不正确, 应为: 使用者表名_使用者id` });
                    }
                }
            ]
        };

        if (!await ctx.validate(userRule, { used })) return sendToWormhole(stream);
        if (!await ctx.validate(rule, { BucketName })) return sendToWormhole(stream);

        const fileUploadData = {
            BucketName,
            fileName: stream.filename,
            fileBody: stream
        };

        const cosPutObjectRes = await service.utilsFilesCos.putObject(fileUploadData);

        if (cosPutObjectRes.statusCode !== 200) {
            return ctx.returnBody(200, '上传文件失败', cosPutObjectRes);
        }

        const fileSaveData = {
            used,
            user_id: ctx.token.user_id,
            title: stream.filename,
            link: cosPutObjectRes.Location,
            type: BucketName,
            time: Date.now()
        };

        const result = await app.mysql.insert(config.baseTable.files, fileSaveData);

        const returnData = {
            success: true,
            file_path: cosPutObjectRes.Location,
            file_id: result.insertId
        };

        ctx.returnBody(200, '上传文件成功', returnData);
    }

    /**
  * @api {put} /UtilsFile/:id 更改数据
  * @apiGroup UtilsFile
  */
    async update() {
        const { ctx } = this;
        console.log(213);
        ctx.returnBody(200, '进入了更改数据接口');
    }

    /**
  * @api {delete} /UtilsFile/:id 删除数据
  * @apiGroup UtilsFile
  */
    async destroy() {
        const { ctx, service, app, config } = this;
        const BucketName = ctx.headers['bucket-name'];
        const { fileName } = ctx.request.body;
        const { id } = ctx.params;

        if (!await ctx.validate(rule, { BucketName })) return;

        const fileDeleteData = {
            fileName,
            BucketName
        };

        const conn = await app.mysql.beginTransaction();

        try {
            const result = await conn.delete(config.baseTable.files, { id });
            if (result.affectedRows !== 1) {
                return ctx.returnBody(404, '文件不存在');
            }
            const cosDeleteObjectRes = await service.utilsFilesCos.deleteObject(fileDeleteData);
            if (cosDeleteObjectRes.statusCode > 300) {
                await conn.rollback();
                return ctx.returnBody(400, '删除文件失败', cosDeleteObjectRes);
            }
            await conn.commit();
            return ctx.returnBody(200, '删除成功', cosDeleteObjectRes);
        } catch (error) {
            // error, rollback
            await conn.rollback(); // 一定记得捕获异常后回滚事务！！
            throw error;
        }
    }
}

module.exports = UtilsFile;
